package com.runa.rccprotocol.analysis;

import com.alibaba.fastjson.JSON;
import com.runa.persistence.service.LogService;
import com.runa.persistence.util.LogUtil;
import com.runa.protocol.analysis.MetaBufferAnalysis;
import com.runa.protocol.analysis.ShellBufferAnalysis;
import com.runa.protocol.dto.DTUEvent;
import com.runa.protocol.dto.DTUSysinfo;
import com.runa.protocol.dto.DtuReport;
import com.runa.protocol.dto.DtuReportAck;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.enums.DtuModel;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.ConcentratorElectric;
import com.runa.rccprotocol.dto.equdata.ConcenReportData;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhuj
 */
@Slf4j
public class DtuHDBufferAnalysis extends ShellBufferAnalysis<byte[]> {


    public DtuHDBufferAnalysis(MetaBufferAnalysis analysis) {
        super(analysis, 1024);
    }

    @Override
    public int fill(byte[] data, int length, String n) {
        interData = null;
        int begin;
        for (begin = 0; begin < length; begin++) {
            if ((data[begin] & 0xff) == 0x7B) {
                if ((data[begin + 1] & 0xff) == 0x7B) {
                    begin++;
                }
                break;
            }
        }
        if (length < begin + 4) {
            return -1;
        }
        int len = ((data[begin + 2] & 0xff) << 8) + (data[begin + 3] & 0xff);
        if (length < begin + len) {
            return -1;
        }
        if ((data[begin + len - 1] & 0xff) != 0x7B) {
            return 0;
        }
        int code = data[begin + 1] & 0xff;
        int count = 0;
        for (int index = begin + 4; index < begin + 15; index++) {
            if (data[index] < 0x30 || data[index] > 0x39) {
                break;
            }
            count++;
        }
        netEquNo = new String(data, begin + 4, count);
        if (code == 1) {
            DtuReport register = new DtuReport(netEquNo);
            register.setMustAck(true);
            DtuReportAck ack = DtuReportAck.createAck(DtuModel.HongDian7710, netEquNo);
            register.setAck(ack);
            LogUtil.linkDetect(netEquNo, "瑞纳DTU", data, length, "宏电心跳");
            interData = register;
        } else if (code == 9) {
            LogService.saveErrorLog("瑞纳", "DTU", data, length);
            //上报sysinfo
            if (length > 17 && ByteUtil.byteToInt(data, 15, ByteOrder.ABCD) >> 8 == 0x222222) {
                String s = ByteUtil.byteToHexString(data, 18, length - 19);
                String string = hexStringToString(s);
                if (string.contains("powerdown")) {
                    DTUEvent dtuEvent = JSON.parseObject(string, DTUEvent.class);
                    ConcentratorElectric electric = new ConcentratorElectric(dtuEvent.getId());
//                    ConcentratorElectric electric = newComm ConcentratorElectric("13880066");
                    ConcenReportData reportData = new ConcenReportData();
                    reportData.setTime(new Date());
                    reportData.setDate(new Date());
                    reportData.setEvent("powerdown");
                    electric.setReportData(reportData);
                    interData = electric;
                } else {
                    DTUSysinfo dtuSysinfo = JSON.parseObject(string, DTUSysinfo.class);
                    String softver = dtuSysinfo.getParam().getData().getSoftver();
                    String modemIccid = dtuSysinfo.getParam().getData().getModemIccid();
                    String modemCsq = dtuSysinfo.getParam().getData().getModemCsq();
                    ConcentratorElectric electric = new ConcentratorElectric(dtuSysinfo.getId());
//                    ConcentratorElectric electric = newComm ConcentratorElectric("13880066");
                    ConcenReportData reportData = new ConcenReportData();
                    reportData.setTime(new Date());
                    reportData.setDate(new Date());
                    reportData.setVer(softver);
                    reportData.setIccid(modemIccid);
                    reportData.setCsq(Integer.parseInt(modemCsq));
                    electric.setReportData(reportData);
                    interData = electric;
                }
                return 0;
            } else if (new String(data, 15, 3).equals("<<<")) {
                String payload = new String(data, 15, 264);
                String[] kvs = payload.split("\r\n");
                Map<String, String> param = Lists.list(kvs).stream().collect(Collectors.toMap(kv -> kv.substring(0, kv.indexOf(":")), kv -> kv.substring(kv.indexOf(":") + 1)));
                ConcentratorElectric electric = new ConcentratorElectric(param.get("DTUID"));
                ConcenReportData reportData = new ConcenReportData();
                reportData.setTime(new Date());
                reportData.setDate(new Date());
                reportData.setVer(param.get("Vbat"));
                reportData.setIccid(param.get("Iccid"));
                reportData.setCsq(Integer.parseInt(param.get("CSQ")));
                electric.setReportData(reportData);
                interData = electric;
                return 0;
            }

            int size = len - 16;
            if (size > buffer.length) {
                expand(size);
            }
            System.arraycopy(data, begin + 15, buffer, 0, size);
            int codeT = analysis.fill(buffer, size, netEquNo);
            if (codeT == -1) return 0;
            interData = analysis.gain();
        }
        return length - begin - len;
    }

    private static String hexStringToString(String s) {
        if (s == null || s.isEmpty()) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
        }
        s = new String(baKeyword, StandardCharsets.UTF_8);
        return s;
    }

    public static void main(String[] args) {
        DtuHDBufferAnalysis dtuHDBufferAnalysis = new DtuHDBufferAnalysis(new RunaRepeaterAnalysis());
//        String s="7B090082383030303031343000000068815772280900111181651F9012000000000000000000000014800000003C1D0600001E000000000000000000326400003000050040000000000001000000000000000000002822874701491921082320000026000000000000000000000000000043340000000000000000000000004D167B";
//        String s="7B 01 00 16 32 33 30 30 30 33 34 39 00 00 00 00 00 00 00 00 00 7B";
//        String s="7B09C07B09003932333030303235390000000103240000000000000000000000000000000000000000000000000000000000000000000000007B";
//        String s = "682591540049008F41812E1F900000000000081204170008160100001A9070320035339888042C308900045900001900083410";
        String s = "7B0900233134313830323438000000FEFEFE68819151302300111184031F900076167B";
//        String s="7B0900B4303438373032323000000068A4A4680800726984204224232E0CE13000000C05537888008C1005000000000E560000008B64C5E98D2A705805000B3A4287000A5A03040A5E47030A6256000B26347510046D270BF92C4C05541484004C1263944648CC100500000000CC20050000000021362A42EC7E1E3A8C0105281284008C0112104199478C1105000000008C21050000000055E085278201EC7E01378C4014300000008C80401420000000BF167B  ";
//        String s="7B01001632333030303334390000000000000000007B";
        byte[] bytes = ByteUtil.hexStringToByte(s);
        dtuHDBufferAnalysis.fill(bytes, bytes.length, "");
        System.out.println(JSON.toJSONString(dtuHDBufferAnalysis.gain()));


//        String s = "7B 09 00 A7 31 32 31 32 31 32 31 32 00 00 00 " +
//                "22 22 22 " +
//                "7B 22 49 64 22 3A 22 31 32 31 32 31 32 31 32 22 2C 22 46 75 6E 63 22 3A 22 75 70 22 2C 22 53 65 71 22 3A 22 32 32 39 62 63 32 39 34 2D 38 33 36 66 2D 34 30 62 32 2D 62 31 63 36 2D 31 62 31 36 33 33 34 35 31 38 61 66 22 2C 22 54 69 6D 65 22 3A 31 36 36 38 37 36 30 36 30 35 2C 22 50 61 72 61 6D 22 3A 7B 22 54 79 70 65 22 3A 22 65 76 65 6E 74 22 2C 22 44 61 74 61 22 3A 5B 7B 22 45 76 65 6E 74 22 3A 22 70 6F 77 65 72 64 6F 77 6E 22 7D 5D 7D 7D " +
//                "7B  ".trim();
//        System.out.println(s);
    }



}
